package com.example.comment_oa.aspact;

import com.example.comment_oa.response.AjaxResponse;
import com.example.comment_oa.util.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Slf4j
@Aspect
@Component
public class refresAspect {
    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Pointcut("execution(* com.example..controller..*Controller.*(..))")
    public void pc(){}

    @AfterReturning(value = "pc()",returning = "value")
    public void round(JoinPoint jp, Object value) {
        AjaxResponse ajaxResponse = (AjaxResponse) value;
        //从Redis获取已存储的令牌
        Object o = stringRedisTemplate.opsForValue().get("token");
        //如果Redis的令牌没有查询到，证明已过期
        if (o == null) {
            System.err.println("redis已過期");
            ajaxResponse.setCode(403);
        } else {
            //未过期，刷新令牌，并将新令牌存入Redis
            // 获取请求
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String jwt = request.getHeader("Authorization");
            Claims claims = JwtUtil.parseJWT(jwt);
            if(claims==null){
                ajaxResponse.setCode(403);
                throw new IncorrectCredentialsException();
            }
            if(claims.getExpiration()==null){
                ajaxResponse.setCode(403);
            }
            if (JwtUtil.isTokenExpired(claims.getExpiration())) {
                System.err.println("前端已過期");
                ajaxResponse.setCode(403);
            }
            //获取username,生成新的劲jwt,返回前端and Redis
            String username = claims.getId();
            String token = JwtUtil.createJWT(username, "back", "user", 1000 * 60 * 60 * 2);
            ajaxResponse.setToken(token);
            stringRedisTemplate.opsForValue().set("token", token, 2, TimeUnit.HOURS);
        }
    }
}
